package com.imageim.yimirror.common.ui.btn;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Region;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import com.imageim.yimirror.common.util.UIUtils;

/**
 * Created by Bruce.Zhou on 2018/7/23 15:00.
 * Email: 907160968@qq.com
 */

public class BtnEffect extends SurfaceView implements Runnable {

    private Paint paint;
    private float cx;
    private float cy;
    private float radius; // 半径
    private Path mPath;
    private static final int STATE_UNSELECTED = 0;
    private static final int STATE_SELECTED = 1;
    private int state = STATE_UNSELECTED;
    private SurfaceHolder holder;
    private boolean isDrawing;
    private String text = "智能分析";
    private static final int fontSize = 28; // 字体大小
    private static final int RECT_RADIUS = 8; // 圆角大小
    private static final int BORDER_WIDTH = 2; // 边框宽度
    private static final int circleColor = Color.parseColor("#f63854"); // 选中颜色
    private boolean touchable = true;

    public interface OnSelectListener {
        void onSelect(BtnEffect btn, boolean isSelected);
    }

    private OnSelectListener selectListener;

    public void setSelectListener(OnSelectListener selectListener) {
        this.selectListener = selectListener;
    }

    public BtnEffect(Context context) {
        super(context);
        init();
    }

    public BtnEffect(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public BtnEffect(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(BORDER_WIDTH);
        paint.setAntiAlias(true);
        paint.setTextSize(fontSize);
        paint.setStrokeJoin(Paint.Join.ROUND);
        mPath = new Path();
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        if (!touchable) {
                            return true;
                        }
                        cx = motionEvent.getX();
                        cy = motionEvent.getY();
                        //                        toggleState();
                        if (selectListener != null) {
                            selectListener.onSelect(BtnEffect.this, isSelected());
                        }
                        break;
                    default:
                        break;
                }
                return true;
            }
        });
        setZOrderOnTop(true);
        holder = getHolder();
        holder.setFormat(PixelFormat.TRANSLUCENT);
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                if (isDrawing == false) {
                    isDrawing = true;
                    new Thread(BtnEffect.this).start();
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                isDrawing = false;
            }
        });
    } // init

    public void setTouchable(boolean touchable) {
        this.touchable = touchable;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        cx = getWidth() / 2.0f;
        cy = getHeight() / 2.0f;
    }

    private void toggleState() {
        if (state == STATE_UNSELECTED) {
            setState(STATE_SELECTED);
        } else {
            setState(STATE_UNSELECTED);
        }
    }

    private void setState(int state) {
        if (this.state != state) {
            this.state = state;
        }
        //        if (state == STATE_UNSELECTED) {
        //            radius = 0;
        //        } else if (state == STATE_SELECTED) {
        //        }
    }

    @Override
    public void setSelected(boolean selected) {
        if (touchable) {
            if (selected) {
                setState(STATE_SELECTED);
            } else {
                setState(STATE_UNSELECTED);
            }
        }
    }

    @Override
    public boolean isSelected() {
        return state != STATE_UNSELECTED;
    }

    public void setText(String text) {
        this.text = text;
    }

    @Override
    public void run() {
        while (isDrawing) {
            draw();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static final int SPEED = 9;
    private boolean canDraw = true;

    public void setCanDraw(boolean canDraw) {
        this.canDraw = canDraw;
    }

    private void draw() {
        Canvas canvas = holder.lockCanvas();
        if (canvas == null) {
            return;
        }
        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        if (canDraw) {
            if (state == STATE_SELECTED) {
                //            canvas.save();
                mPath.reset();
                mPath.addRoundRect(0, 0, getWidth(), getHeight(), RECT_RADIUS, RECT_RADIUS, Path.Direction.CCW);
                canvas.clipPath(mPath, Region.Op.REPLACE);
                // draw scene start
                paint.setStyle(Paint.Style.FILL);
                paint.setColor(circleColor);
                canvas.drawCircle(cx, cy, radius, paint);
                if (radius < 1.2f * Math.max(cx, getWidth() - cx) && state == STATE_SELECTED) {
                    radius += SPEED;
                }
                // draw scene end
                //            canvas.restore();
            } else {
                //            canvas.save();
                mPath.reset();
                mPath.addRoundRect(0, 0, getWidth(), getHeight(), RECT_RADIUS, RECT_RADIUS, Path.Direction.CCW);
                canvas.clipPath(mPath, Region.Op.REPLACE);
                // draw scene start
                paint.setStyle(Paint.Style.FILL);
                paint.setColor(circleColor);
                canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
                if (radius > 0 && state == STATE_UNSELECTED) {
                    radius -= SPEED;
                    if (radius <= 0) {
                        radius = 0;
                    }
                }
                // draw scene end
                //            canvas.restore();

                // draw outside round rect bounds
                paint.setStyle(Paint.Style.STROKE);
                paint.setColor(Color.WHITE);
                canvas.drawRoundRect(0, 0, getWidth(), getHeight(), RECT_RADIUS, RECT_RADIUS, paint);
            }
            //        // draw outside round rect bounds
            //        paint.setStyle(Paint.Style.STROKE);
            //        paint.setColor(Color.WHITE);
            //        canvas.drawRoundRect(0, 0, getWidth(), getHeight(), RECT_RADIUS, RECT_RADIUS, paint);
            // draw text
            if (!TextUtils.isEmpty(text)) {
                paint.setStyle(Paint.Style.FILL);
                paint.setColor(Color.WHITE);
                canvas.drawText(text, getWidth() / 2 - UIUtils.getTextWidth(text, paint) / 2, getHeight() / 2
                        + UIUtils.getTextHeight(text, paint) / 2, paint);

            }
        }

        Surface surface = holder.getSurface();
        if (holder != null && surface != null) {
            try {
                holder.unlockCanvasAndPost(canvas);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        isDrawing = false;
    }

    public void setTextSize(int textSize) {
        if (paint != null) {
            paint.setTextSize(textSize);
        }
    }

}
